#pragma once
#include <OgreNewt.h>
#include "OgreSceneNode.h"
#include "OgreEntity.h"
#include "util.h"

//////////////////////////////////////////////////////////////////////////
//Used the identify the gameobj subclass plus the Ground.
//Ground is *not* gameobj but it has an ObjType.
//All three line and corresponding block in gameobj.cpp *must* be consistent.
const int _OBJ_TYPE_NUM = 5;
enum ObjType{OT_ERROR_TYPE,OT_BLOCK,OT_BIRD,OT_PIG,OT_GROUND};
extern char *objTypeToString[_OBJ_TYPE_NUM];
//////////////////////////////////////////////////////////////////////////

class GameObj
{
	
	//////////////////////////////////////////////////////////////////////////
private:
	int _healthPoint;
	int _mass;
	static int _idCnt;
	int _id;
protected:
	virtual void setHealthPoint(int val); 
	virtual char *getMeshName()=0;
	virtual char *getMaterialName()=0;
public:
	int getMass() const { return _mass;}
	void setMass(int val) { _mass = val;}
	
public:
	int getID(){
		return _id;
	}
	//body
	//////////////////////////////////////////////////////////////////////////
protected: //the following methods are used to set off some motion
	virtual void destroy()=0;// this gameObj is killed
public:
	//to indentify the gameobj subclass
	int getHealthPoint() const;
	virtual ObjType getType() const =0;

	//the only way to modify the HP
	virtual void decreaseHP(int delta){
		ASSERT(delta>0);
		if(delta>getHealthPoint()){
			destroy();
		}
		setHealthPoint(getHealthPoint()-delta);
	} 

	//called the get the birds ready, set the materiel etc
	virtual void getReady()=0;	
	//called by the physics module. inform the game object that a collision happens
	virtual void collide(){}
	virtual void init(Ogre::Vector3& size, Ogre::Vector3& pos, Ogre::Quaternion& orient);
	//////////////////////////////////////////////////////////////////////////
	//getters
	Ogre::Vector3 getPosition();
	OgreNewt::Body* getBody(){return body;}
	virtual const OgreNewt::MaterialID* getMaterialID();
	const std::string getName() const;
	Ogre::Entity* getEntity() {return entity;}
	//////////////////////////////////////////////////////////////////////////
	Ogre::SceneNode *sceneNode;
	Ogre::Entity *entity;
	OgreNewt::Body *body;
public:
	static const OgreNewt::MaterialID *materialID;
	//////////////////////////////////////////////////////////////////////////
public:
	GameObj(void);
	virtual ~GameObj(void);
};

